package com.itheima.core;

import com.itheima.support.CodeProperties;
import com.itheima.support.ColDesc;
import com.itheima.support.StringUtil;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.ClasspathResourceLoader;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.kit.GenKit;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Component
public class GenerateCode {
	
	@Autowired
	private SQLManager sqlManager;

//	@Value("${system.basePck}")
//	private String basePck;
	@Resource
	private CodeProperties codeProperties;
	
	private List<ColDesc> getTableDesc(String tableName) throws Exception{
		Map params = new HashMap();
		String sqlId = "codegenerator.generator.select";
		if(tableName.indexOf(".") != -1){
			params.put("schema", tableName.substring(0, tableName.indexOf(".")));
			params.put("tableName", tableName.substring(tableName.indexOf(".") + 1));
			sqlId = "codegenerate.generate.selectBySchema";
		}else{
			params.put("tableName", tableName.toLowerCase());
			params.put("catalog", sqlManager.getDs().getMaster().getCatalog());
		}
		return (List<ColDesc>) sqlManager.select(sqlId, ColDesc.class, params);
	}
	
	private boolean createFile(String filepath,String basePkg,String sub_pkg,String btl,
			String table_name,String pojoName,GroupTemplate gt,boolean rebuild) throws Exception{
		
		String _pkg = basePkg +"." + (StringUtil.isEmpty(sub_pkg) ? "" : sub_pkg);
		
		String file = filepath+File.separator+_pkg.replace('.',File.separatorChar);

		Map rootMap = new HashMap();
		rootMap.put("basePkg", basePkg);
		rootMap.put("pojoName", pojoName);
		rootMap.put("tableName", table_name);
		rootMap.put("pk", "");
		
		if(sub_pkg!=null && sub_pkg.equals("pojo")) {
			List<ColDesc> cols = getTableDesc(table_name);
			rootMap.put("cols", cols);
			for(ColDesc col : cols) {
				if(col.getIskey() == 1) {
					rootMap.put("pk", col.getColumnName());
					break;
				}
			}
		}
		
		Template template = gt.getTemplate(btl);
		template.binding(rootMap);
		
		File f = new File(file);
		
		f.mkdirs();
		
		String fileName = pojoName + ".java";

		if("mapper".equals(sub_pkg)){
			fileName = pojoName + "Mapper.java";
		}else if("service".equals(sub_pkg)){
			fileName =pojoName + "Service.java";
		}else if("service.impl".equals(sub_pkg)){
			fileName = pojoName + "ServiceImpl.java";
		}else if("web".equals(sub_pkg)){
			fileName = pojoName + "Controller.java";
		}
		
		File target = new File(file,fileName);
		
		if(rebuild == false && target.exists()) {
			return false;
		}
		
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(target);
			template.renderTo(out);
			out.flush();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return true;
	}
	
	private boolean checkPath(String... paths) {
		for(String path : paths) {
			File file = new File(path);
			if(file.exists() == false) {
				System.err.println("路径:" + path + " 不对,请检查Maven模块是否已经创建.");
				return false;
			}
		}
		return true;
	}
	
	public void generator() {
		//beetl
		ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader("templates/");
		
		Configuration cfg = null;
		try {
			cfg = Configuration.defaultConfiguration();
		} catch (IOException e) {
			e.printStackTrace();
		}
		GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
		
		SAXReader reader = new SAXReader();
		try {
			InputStream in = this.getClass().getClassLoader().getResourceAsStream("generatorCode.xml");
			Document document = reader.read(in);
			Element node = document.getRootElement();
			
			Iterator<Element> iterator = node.elementIterator();
			
			String srcPath = GenKit.getJavaSRCPath();
			
			while(iterator.hasNext()) {
				Element ele = iterator.next();
				String table_name = ele.attributeValue("table_name");
				String pojoName = ele.attributeValue("pojoName");
				boolean rebuild = "true".equals(ele.attributeValue("rebuild"));
				
				
				if(checkPath(srcPath) == false) {
					return ;
				}
				
				if(StringUtil.isEmpty(pojoName)){
					pojoName = table_name;
					if(table_name.indexOf(".") != -1){
						pojoName = table_name.substring(table_name.indexOf(".") + 1);
					}
					pojoName = StringUtil.underline2Camel(pojoName, true);
					pojoName = pojoName.substring(0, 1).toUpperCase() + pojoName.substring(1);
				}

				boolean pojo = createFile(replacePath(srcPath,codeProperties.getPojoProjectName()),codeProperties.getBasePck(),"pojo","pojo.btl",table_name,pojoName,gt,rebuild);
				if(pojo)
					System.out.println("============已生成POJO============");

				boolean mapper = createFile(replacePath(srcPath,codeProperties.getMapperProjectName()),codeProperties.getBasePck(),"mapper","mapper.btl",table_name,pojoName,gt,rebuild);
				if(mapper)
					System.out.println("============已生成Mapper============");

				boolean service = createFile(replacePath(srcPath,codeProperties.getServiceProjectName()),codeProperties.getBasePck(),"service","service.btl",table_name,pojoName,gt,rebuild);
				if(service)
					System.out.println("============已生成Service============");

				boolean service_impl = createFile(replacePath(srcPath,codeProperties.getServiceImplProjectName()),codeProperties.getBasePck(),"service.impl","service_impl.btl",table_name,pojoName,gt,rebuild);
				if(service_impl)
					System.out.println("============已生成Service Impl============");
			}
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}

	private String replacePath(String filePath,String projectName){
		return filePath.replace(codeProperties.getCodeProjectName(),projectName);
	}
	
}
